package com.passioneffect.contentmcs {
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.utils.Timer;

	import com.passioneffect.adapter.ContentMovieClipAdapter;
	import com.passioneffect.collection.Iterator;
	import com.passioneffect.display.Component;	

	/**
	 * @author Passion Effect
	 */
	dynamic public class AbstractContentMovieClip extends MovieClip {

		public var adapter : ContentMovieClipAdapter;
		private var tf : TextField;
		private var _lock : Boolean;
		
		private var constraint_mc : DisplayObject;
		protected var inited : Boolean;
		private var doFuncs : Array = [];
		protected var rect : Rectangle;
		protected var data : Object;

		public function AbstractContentMovieClip() {
			rect = new Rectangle();
		}

		public function init(adapter : ContentMovieClipAdapter) : void {
			this.adapter = adapter;
		}

		public function removeConstraint() : void {
			component.removeLayoutValue(adapter);
		}

		protected function removeFromViewList() : void {
			component.removeFromViewList(adapter);
		}

		public function select() : Boolean {
			return component.selectItemMovieClip(this);
		}
		
		protected function over() : void {
			if(isOver())return;
			component.setOverItem(adapter);
		}

		protected function isOver() : Boolean {
			return adapter == component.getOverItem();
		}

		public function getMinX() : Number {
			return component.getMinX();
		}

		public function getMaxX() : Number {
			return component.getMaxX();
		}

		public function getMinY() : Number {
			return component.getMinY();
		}

		public function getMaxY() : Number {
			return component.getMaxY();
		}

		public function getPercentMouseX() : Number {
			var p : Number = mouseX / getLayoutValue().width;
			if(p > 1) {
				return 1;
			}else if(p < 0) {
				return 0;
			}
			
			return p;
		}

		protected function out() : void {
			if(!isOver())return;
			component.setOutItem(adapter);
		}

		public function cancelAllDoLater() : void {
			doFuncs = [];
			this.removeEventListener(Event.ENTER_FRAME, doFuncHandler);
		}

		public function doLater(func : Function) : void {
			
			for(var i : int = 0;i < doFuncs.length;i++) {
				if(doFuncs[i].func == func) {
					this.addEventListener(Event.ENTER_FRAME, doFuncHandler);
					return;
				}
			}
			doFuncs.push({func:func});
			this.addEventListener(Event.ENTER_FRAME, doFuncHandler);
		}

		private function doFuncHandler(evt : Event) : void {
			this.removeEventListener(Event.ENTER_FRAME, doFuncHandler);
			for each(var obj:Object in doFuncs) {
				var func : Function = obj.func;
				func.apply(this);
			}
		}


		public function unselect() : Boolean {
			return component.unselect();
		}

		protected function startUpdateConstraint(mc : DisplayObject) : void {
			if(component.autoLockSelection) {
				component.lockSelect = true;
			}
			
			constraint_mc = mc;
			this.addEventListener(Event.ENTER_FRAME, updateConstraint);
		}

		protected function scrollToItem() : void {
			component.scrollToItem(adapter);
		}

		protected function getDistance() : Number {
			
			
			var rect : Object = getLayoutValue();
			var ox : Number = rect.width / 2;
			var oy : Number = rect.height / 2;
			
			var dx : Number = mouseX - ox;
			var dy : Number = mouseY - oy;
			
			var d : Number = Math.sqrt(dx * dx + dy * dy);
			
			return d;
		}

		protected function getDistanceX() : Number {
			
			var rect : Object = getLayoutValue();
			
			if(component.direction == "horizontal") {
				var ox : Number = rect.width / 2;
				return mouseX - ox;
			}else {
				var oy : Number = rect.height / 2;
				return mouseY - oy;
			}
		}

		protected function getDistanceY() : Number {
			var rect : Object = getLayoutValue();
			
			if(component.direction == "horizontal") {
				var oy : Number = rect.height / 2;
				return mouseY - oy;
			}else {
				var ox : Number = rect.width / 2;
				return mouseX - ox;
			}
		}
		
		public function get selected():Boolean{
			return component.getSelectedItem()==adapter;	
		}
		
		protected function endUpdateConstraint() : void {
			if(component.autoLockSelection) {
				component.lockSelect = false;
			}
			constraint_mc = null;
			this.removeEventListener(Event.ENTER_FRAME, updateConstraint);
		}

		private function updateConstraint(evt : Event) : void {
			setConstraint(constraint_mc.width, constraint_mc.height);
		}

		protected function setLayoutValue(layoutValue : *) : void {
			component.updateLayout(adapter, layoutValue);
		}

		protected function removeLayoutValue() : void {
			component.removeLayoutValue(adapter);
		}

		protected function setAlignItem() : void {
			//comonent.setAlign
		}

		protected function setConstraint(w : Number,h : Number,others : Object = null) : void {
			rect.width = w;
			rect.height = h;
			rect.x = rect.y = 0;
			
			var con : Object;
			
			if(component.direction == "horizontal") {
				con = {xLength:w, yLength:h, width:w, height:h};
			}else {
				con = {xLength:h, yLength:w, width:w, height:h};
			}
			
			for(var i:String in others) {
				con[i] = others[i];
			}
			
			component.updateLayout(adapter, con);
		}

		//this will return contraint or unselectedSize if no constraint
		protected function getLayoutSize() : Object {
			return component.getLayoutSize(adapter);
		}

		protected function getLayoutValue() : Object {
			return component.getLayoutValue(adapter);
		}

		protected function getOtherMCs() : Array {
			var itr : Iterator = component.getItems().iteratorExcept([adapter]);
			var arr : Array = [];
			while(itr.hasNext()) {
				arr.push(itr.next().getMovieClip());
			}
			return arr;
		}

		protected function getOverItem() : ContentMovieClipAdapter {
			return component.getOverItem();
		}

		protected function get index() : int {
			return adapter.getIndex();
		}

		public function get autoRemove() : Boolean {
			return !_lock;
		}

		public function set autoRemove(autoremove : Boolean) : void {
			_lock = !autoremove;
			if(!_lock) {
				removeConstraint();
			}
		}

		protected function get _data() : Object {
			return adapter.data;
		}

		public function set lockMouseScroll(b : Boolean) : void {
			component.lockMouseScroll = b;
		}

		public function get lockMouseScroll() : Boolean {
			return component.lockMouseScroll;
		}

		public function get rootComponent() : Component {
			var comp : Component = component;
			while(comp.parentComponent) {
				comp = comp.parentComponent;
			}
			return comp;
		}

		public function get component() : Component {
			return adapter.getComponent();
		}

		public function get type() : String {
			return component.type;
		}

		public function hitTest(mc : DisplayObject) : Boolean {
			var r : Rectangle = mc.getRect(this);
			if(r.contains(mouseX, mouseY)) {
				return true;
			}
			return false;
		}
	}
}
